package com.ruolin.micro.gateway.server.route.resolver;

import com.alibaba.fastjson.JSON;
import com.ruolin.micro.gateway.server.constant.FormType;
import com.ruolin.micro.gateway.server.metadata.MethodRouteMetadata;
import com.ruolin.micro.gateway.server.route.RouteDefinitionLocator;
import com.ruolin.micro.gateway.server.servlet.bean.RouterBeanDefinition;
import com.ruolin.micro.gateway.server.utils.RequestJsonUtils;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class RequestBodyParameterResolver extends AbstractRequestParameterResolver {
    @Autowired
    private RouteDefinitionLocator routeDefinitionLocator;

    @Override
    public Object[] resolve(HttpServletRequest request, HttpServletResponse response) {
        Map<String, Object> requestMap = new HashMap<>();

        try {
            String requestBody = RequestJsonUtils.getRequestPostStr(request);
            requestMap = JSON.parseObject(requestBody, Map.class);
            String requestRoute = request.getPathInfo();
            List<RouterBeanDefinition> routerBeanDefinitions = routeDefinitionLocator.getRouteDefinitions();
            MethodRouteMetadata methodRouteMetadata = getMethodRouteMetadata(requestRoute, routerBeanDefinitions);
            Map<String, Object> fieldMap = methodRouteMetadata.getFieldMap();
            int objectIndex = methodRouteMetadata.getObjectIndex();
            String objectStr = methodRouteMetadata.getParameterTypes().get(objectIndex);
            requestMap.entrySet().forEach(e -> {
                if (!fieldMap.containsKey(e.getKey())) {
                    throw new IllegalArgumentException("this [filed::" + e.getKey() + " is not " + objectStr + "'s field,");
                }
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new Object[]{requestMap};
    }

    @Override
    public RequestBodyParameterResolver getResolver() {
        return this;
    }

    @Override
    public FormType getFormType() {
        return FormType.POST;
    }
}
